<!--
 * @Author: 
 * @Date: 2022-08-08 16:26:50
 * @LastEditTime: 2023-11-14 11:01:42
 * @LastEditors: tzq
 * @Description: 实时视频
 * @FilePath: \bdcar-net\src\views\videoMonitoring\realtimeVideo\index.vue
-->
<template>
  <div class='app-container'>
    <div class="left" v-loading="loading" id="rightDom">
      <div class="title">
        <div class="rectangle"></div>监管对象列表
        <el-icon :size="20" @click="getTreeData" style="position: absolute;right: 27px;cursor: pointer;" title="刷新树">
          <Refresh />
        </el-icon>
      </div>
      <currentTree class="leftTree" :filterShow="true" :treeList="treeList" ref="myTree"></currentTree>
      <div class="move-img" id="moveImg" v-move></div>
    </div>
    <div class="right" id="container">
      <div class="head">
        <div class="close-all-btn" @click="closeAllVedio()">全部关闭</div>
        <div style="margin-left:auto">
          <img v-for="v in videoBtns" :src="myRequire(v)" @click="videosMax = v.value;" />
        </div>
      </div>
      <div class="body">
        <div class="body-video" :class="getVideoClass(videosMax)" v-for="(value, key, index) in videoHash" :key="index"
          v-show="index < videosMax">
          <video class="my-video" controls :id="key" muted></video>
          <div class="video-title">
            <span class='close' @click="closeVideo(key)"></span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup name="RealtimeVideo">
//是否加载了当前页面
let actived = true;
import { getVideoTree } from "@/api/videoMonitoring/realtimeVideo"
import currentTree from "./currentTree.vue"
const { proxy } = getCurrentInstance();
import flvjs from "flv.js"
const loading = ref(false);
const treeList = ref([]);
const videosMax = ref(1);
const videoBtns = ref([
  { value: 1, class: "1screen" },
  { value: 2, class: "2screen" },
  { value: 4, class: "4screen" },
  { value: 6, class: "6screen" },
  { value: 9, class: "9screen" },
  { value: 16, class: "16screen" },
]);
//视频dom元素数组
const videoHash = ref({});
//当前处于播放的hash
const hashObj = ref({});
const myTree = ref(null);
//构造视频元素
for (let i = 0; i < 16; i++) {
  videoHash.value['video' + i] = {
    title: null,
    dom: null,
    id: null
  };
};
function myRequire(obj) {
  let extra = '.png';
  if (videosMax.value == obj.value) {
    extra = '-1.png'
  }
  return new URL(`../../../assets/img/video/${obj.class}${extra}`, import.meta.url).href
}
getTreeData();
function getTreeData() {
  loading.value = true
  getVideoTree({ onlyOnline: true }).then(result => {
    loading.value = false
    if (result.code == 200) {
      let object = result.data;
      treeList.value = object;
    }
  });
}
function playSelectVideo(domId, url) {
  if (flvjs.isSupported()) {
    let videoElement, videoObj;
    videoElement = document.getElementById(domId);
    videoObj = flvjs.createPlayer({
      type: 'flv',
      isLive: true,
      // hasAudio: false,
      url: GlobalSetting.IotConfig.videoWS + url,
    }, {
      enableWorker: false, //不启用分离线程
      enableStashBuffer: false, //关闭IO隐藏缓冲区
      reuseRedirectedURL: true, //重用301/302重定向url，用于随后的请求，如查找、重新连接等。
      autoCleanupSourceBuffer: true, //自动清除缓存
      stashInitialSize: 500,// 减少首桢显示等待时长
    });

    videoHash.value[domId].dom = videoObj

    videoObj.attachMediaElement(videoElement);
    videoObj.load();
    videoObj.play();

    //定时方法是为了用户离开页面视频是实时播放的,暂停按钮无用
    setInterval(function () {
      if (videoElement.buffered.length > 0 && !actived) {
        const end = videoElement.buffered.end(0); // 视频结尾时间
        const current = videoElement.currentTime; //  视频当前时间
        const diff = end - current; // 相差时间

        const diffCritical = 4; // 这里设定了超过4秒以上就进行跳转
        const diffSpeedUp = 1; // 这里设置了超过1秒以上则进行视频加速播放
        const maxPlaybackRate = 4; // 自定义设置允许的最大播放速度
        let playbackRate = 1.0; // 播放速度
        if (diff > diffCritical) {
          //  flvPlayer.load();
          videoElement.currentTime = end - 1.5;
          playbackRate = Math.max(1, Math.min(diffCritical, 16));
        } else if (diff > diffSpeedUp) {
          playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16));
        }
        videoElement.playbackRate = playbackRate;
        if (videoElement.paused) {
          videoElement.play();
        }
      }
    }, 0);
  } else {
    console.log("暂不支持flv.js")
  }
}
function closeVideo(key) {
  if (!videoHash.value[key].dom && !videoHash.value[key].title && !videoHash.value[key].id) return
  if (videoHash.value[key].dom) {
    videoHash.value[key].dom.pause()
    videoHash.value[key].dom.unload()
    videoHash.value[key].dom.detachMediaElement()
    videoHash.value[key].dom.destroy()
    videoHash.value[key].dom = null;
  }
  videoHash.value[key].title = null;
  delete hashObj.value[videoHash.value[key].id];
  videoHash.value[key].id = null;

  let arrKeyNode = []
  for (let key in videoHash.value) {
    if (videoHash.value[key].title) {
      arrKeyNode.push(videoHash.value[key].id)
    }
  }
  myTree.value.$refs.myTree.setCheckedKeys(arrKeyNode)
}
function closeAllVedio() {
  for (let i = 0; i < 16; i++) {
    closeVideo('video' + i);
  }
}
function handleCheck(data, e) {
  let hashListLength = 0;
  let addList = []  //本次应该播放的视频列表      
  let deleteVideos = []  // 本次应该停止播放的视频列表  
  let checkObj = {}   //本次勾选上的所有视频播放hash

  // 找到需要播放的视频线添加到数组
  e.checkedNodes.forEach(v => {
    if (v.type == 4) {
      checkObj[v.id] = v
      if (!hashObj.value.hasOwnProperty(v.id)) {
        addList.push(v)
        hashObj.value[v.id] = v
      }
    }
  });

  // 找到停止播放的视频关闭
  Object.keys(hashObj.value).forEach(key => {
    const v = hashObj.value[key]
    if (!checkObj.hasOwnProperty(v.id)) {
      deleteVideos.push(v)
      delete hashObj.value[v.id]
      for (let key in videoHash.value) {
        if (videoHash.value[key].id == v.id) {
          closeVideo(key);
          break;
        }
      }
    }
  })
  hashListLength = Object.keys(hashObj.value).length
  //如果视频数目为0就不执行
  if (hashListLength > 16) {
    proxy.$modal.msgError("选择视频数目不可超过16");
    nextTick(() => {
      // 取消当前提示超过视频数目的勾选
      addList.forEach(v => {
        myTree.value.$refs.myTree.setChecked(v.id, false);
        delete hashObj.value[v.id];
      })
    })
    return
  }

  console.log("取消", deleteVideos);
  console.log("添加", addList);
  console.log("当前", hashObj.value);

  function autoGetCurrentNum(length) {
    let list = [1, 2, 4, 6, 9, 16];
    let i = 0;
    while (list[i] < length) {
      i++
    }
    return list[i]
  }
  // 如果当前视频数目不够播放则扩展到下一级别
  if (hashListLength > videosMax.value) videosMax.value = autoGetCurrentNum(hashListLength);

  let baseIndex = 0, flag = true;
  for (let i = 0; i < addList.length; i++) {
    flag = true;
    do {
      let key = 'video' + baseIndex
      // 如果找到了一个没有被占用的则跳出循环
      if (!videoHash.value[key].id) {
        flag = false;
        let dvo = addList[i].deviceId;
        let channel = addList[i].id.charAt(addList[i].id.length - 1);
        videoHash.value[key].title = addList[i].deviceId + addList[i].label;
        videoHash.value[key].id = addList[i].id;
        playSelectVideo(key, dvo + '_' + channel + '.media');
      } else {
        baseIndex++;
      }
    } while (flag && baseIndex < 16)
  }
}
function getVideoClass(param) {
  let _hash = {
    1: "oneVideo",
    2: "twoVideo",
    4: "fourVideo",
    6: "sixVideo",
    9: "nineVideo",
    16: "sixteenVideo",
  };
  return _hash[param]
}
const vMove = {
  beforeMount: (el) => {
    // 在元素上做些操作
    el.onmousedown = function (e) {
      let init = e.clientX;
      //要移动的右侧窗体
      let parent = document.getElementById("rightDom");
      let initWidth = parent.offsetWidth;
      document.onselectstart = () => {
        return false
      };
      document.ondragstart = () => {
        return false
      };
      let minWidth = 270;
      let maxWidth = 600;
      //被动移动的左侧窗体
      let otherDom = document.getElementById("container");
      let OtherinitWidth = otherDom.offsetWidth;
      let moveDom = document.getElementById("moveImg");
      let moveinitLeft = moveDom.offsetLeft;
      document.onmousemove = function (e) {
        let end = e.clientX;

        if (initWidth + end - init > minWidth && initWidth + end - init < maxWidth) {
          parent.style.width = initWidth + end - init + "px"
          moveDom.style.left = moveinitLeft + end - init + "px"
          otherDom.style.width = OtherinitWidth - end + init + "px";
        }
        else return
      };
      document.onmouseup = function () {
        document.onselectstart = null;
        document.ondragstart = null;
        document.onmousemove = document.onmouseup = null;
      };
    };
  }
}
onActivated(() => {
  actived = true;
})
onDeactivated(() => {
  actived = false;
})
defineExpose({
  handleCheck
});
</script>
<style scoped lang="scss">
.left {
  width: 280px;
  height: 100%;
  background: #fff;
  margin-right: 16px;
  position: absolute;
  left: 0;

  .move-img {
    background: url("../../../assets/img/moving.png") no-repeat center;
    width: 10px;
    height: 100%;
    cursor: col-resize;
    position: absolute;
    left: 270px;
    top: 0;
  }

  .title {
    height: 31px;
    font-weight: 600;
    color: #424242;
    background-color: #e6efff;
    display: flex;
    align-items: center;
    margin: 16px 20px;
    margin-bottom: 0;
    font-size: 16px;
    color: #424242;
    display: flex;
    align-items: center;
  }

  .leftTree {
    width: calc(100% - 40px);
    height: calc(100% - 70px) !important;
    margin-left: 20px;
    margin-top: 5px;
  }
}

.right {
  width: calc(100% - 296px);
  height: 100%;
  display: inline-block;
  position: absolute;
  right: 0;
  background: #fff;

  .head {
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-right: 60px;

    .close-all-btn {
      background-color: var(--el-color-primary);
      font-size: 12px;
      line-height: 24px;
      width: 74px;
      text-align: center;
      margin-left: 20px;
      margin-right: auto;
      cursor: pointer;
    }

    img {
      margin: 0 10px;
      cursor: pointer;
    }
  }

  .body {
    margin: 0 18px;
    width: calc(100% - 40px);
    height: calc(100% - 40px);

    .body-video {
      float: left;
      transition: all 0.5s;
      position: relative;

    }

    .oneVideo {
      width: 100%;
      height: 100%;
    }

    .twoVideo {
      width: 100%;
      height: 50%;
    }

    .fourVideo {
      width: 50%;
      height: 50%;
    }

    .sixVideo {
      width: calc(100% / 3);
      height: calc(100% / 3);

      &:first-of-type {
        width: 66.66%;
        height: 66.66%;
      }

      &:nth-of-type(5) {
        width: 33.3%;
      }

      &:nth-of-type(6) {
        width: 33.35%;
      }
    }

    .nineVideo {
      // width: calc(100% / 3);
      width: 33.3%;
      height: calc(100% / 3);
    }

    .sixteenVideo {
      width: 25%;
      height: 25%;
    }

    .my-video {
      width: 100%;
      height: 100%;
      object-fit: fill;
      background-color: black;
    }

    .video-title {
      position: absolute;
      // background-color: rgba(0, 0, 0, 0.5);
      color: #fff;
      top: 0;
      left: 0;
      line-height: 24px;
      padding-left: 10px;
      width: 100%;
      box-sizing: border-box;

      .close {
        position: absolute;
        right: 12px;
        background: url("../../../assets/img/video/closenew.png") no-repeat center;
        width: 22px;
        height: 22px;
        cursor: pointer;
      }
    }
  }
}
</style>